#pragma once

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

enum
{
    SHMGET_ERR = 1,
    FTOK_ERR
};

const char *pathname = "/home/lkm/";
int proj_id = 0x666;

class SharedMeory
{
    static const int defaultsize = 4096; // 默认创建共享内存大小
public:
    SharedMeory() {}
    ~SharedMeory() {}

private:
    static key_t getKey()
    {
        key_t k = ftok(pathname, proj_id);
        if (k < 0)
        {
            perror("ftok");
            exit(FTOK_ERR);
        }

        return k;
    }

    static int sharedMemHelper(int shmflg, size_t size)
    {
        key_t key = getKey();
        int shmId = shmget(key, size, shmflg);
        if (shmId < 0)
        {
            perror("shmget");
            exit(SHMGET_ERR);
        }
        std::cout << "shared memory create success, shmId: " << shmId << std::endl;

        return shmId;
    }

public:
    static int createShm(int size = defaultsize)
    {
        int shmId = sharedMemHelper(IPC_CREAT | IPC_EXCL | 0666, size);
        return shmId;
    }

    static int getShm()
    {
        int shmId = sharedMemHelper(IPC_CREAT, defaultsize);
        return shmId;
    }

};

#define FIFO_FILE "/home/lkm/code/SharedMemory/myfifo"
#define MODE 0664

enum
{
    FIFO_CREATE_ERR = 1,
    FIFO_DELETE_ERR,
    FIFO_OPEN_ERR
};

//通过管道来使共享内存具有同步互斥
class Init
{
public:
    Init()
    {
        // 创建管道
        int n = mkfifo(FIFO_FILE, MODE);
        if (n == -1)
        {
            perror("mkfifo");
            exit(FIFO_CREATE_ERR);
        }
    }
    ~Init()
    {

        int m = unlink(FIFO_FILE);
        if (m == -1)
        {
            perror("unlink");
            exit(FIFO_DELETE_ERR);
        }
    }
};
